package framework;

import org.apache.commons.lang3.reflect.MethodUtils;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * Title: framework.ProviderReflect<br/>
 * Description: <br/>
 * version: 1.0<br/>
 *
 * @author : hzg<br/>
 * date: 2021/9/13 15:12<br/>
 */
public class ProviderReflect {
    private static final ExecutorService EXECUTOR_SERVICE = Executors.newCachedThreadPool();

    /**
     * Description: 服务的发布<br/>
     * author: hzg <br/>
     * Date: 2021/9/13 15:14 <br/>
     * @param service
     * @param port
     * @return void
     */
    public static void provider(final Object service, int port) throws Exception{
        ServerSocket serverSocket = new ServerSocket(port);
        while(true){
            final Socket socket = serverSocket.accept();
            EXECUTOR_SERVICE.execute(() -> {
                try {
                    ObjectInputStream input = new ObjectInputStream(socket.getInputStream());
                    try {
                        try {
                            //方法名称
                            String methodName = input.readUTF();
                            //方法参数
                            Object[] args = (Object[]) input.readObject();
                            ObjectOutputStream output = new ObjectOutputStream(socket.getOutputStream());
                            try {
                                //方法引用
                                Object result = MethodUtils.invokeExactMethod(service,methodName,args);
                                output.writeObject(result);
                            }catch (Throwable t){
                                output.writeObject(t);
                            }finally {
                                output.close();
                            }
                        }catch (Exception e){
                            e.printStackTrace();
                        }finally {
                            input.close();
                        }
                    }finally {
                       socket.close();
                    }
                }catch (Exception e){
                    e.printStackTrace();
                }
            });
        }
    }
}
